1 /**
2  * Breadthfirst path finding algorithm
3  *
4  * License:
5  *     D version of code is under MIT. The original is under Apache 2.0.
6  * 
7  *     The MIT License (MIT)
8  *
9  *     Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
10  *
11  *     Permission is hereby granted, free of charge, to any person obtaining a copy
12  *     of this software and associated documentation files (the "Software"), to deal
13  *     in the Software without restriction, including without limitation the rights
14  *     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  *     copies of the Software, and to permit persons to whom the Software is
16  *     furnished to do so, subject to the following conditions:
17  *
18  *     The above copyright notice and this permission notice shall be included in all
19  *     copies or substantial portions of the Software.
20  *
21  *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  *     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  *     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  *     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  *     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  *     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  *     SOFTWARE.
28  *
29  * See_Also:
30  *		http://www.redblobgames.com/pathfinding/a-star/implementation.html
31  */
32 module devisualization.util.algorithms.pathfinding.breadthfirst;
33 import devisualization.util.algorithms.pathfinding.defs;
34 deprecated("Killing"):
35 
36 /**
37  * Locates the next node in graph to get to a position
38  *
39  * Params:
40  *    graph	=	The graph of nodes
41  *    start	=	Starting/End position to go to
42  *
43  * Returns:
44  *     An AA mapping a position to another to get to a point
45  */
46 T[T] breadth_first_search(T)(Graph graph, T start) {
47 	Queue!T frontier;
48 	frontier.put(start);
49 	T[T] came_from;
50 	
51 	while(!frontier.empty) {
52 		T current = frontier.get();
53 		foreach(next; graph.neighbors(current)) {
54 			if (next !in came_from) {
55 				frontier.put(next);
56 				came_from[next] = current;
57 			}
58 		}
59 	}
60 	
61 	return came_from;
62 }
63 
64 /**
65  * Locates the next node in graph to get to a position
66  *
67  * Params:
68  *    graph	=	The graph of nodes
69  *    start	=	Starting position to go to
70  *    goal	=	The end position 
71  *
72  * Returns:
73  *     An AA mapping a position to another to get to a point
74  */
75 T[T] breadth_first_search(T)(Graph graph, T start, T goal) {
76 	Queue!T frontier;
77 	frontier.put(start);
78 	T[T] came_from;
79 	
80 	while(!frontier.empty) {
81 		T current = frontier.get();
82 		if (current == goal)
83 			break;
84 		
85 		foreach(next; graph.neighbors(current)) {
86 			if (next !in came_from) {
87 				frontier.put(next);
88 				came_from[next] = current;
89 			}
90 		}
91 	}
92 	
93 	return came_from;
94 }
95 
96 unittest {
97 	Graph!string example_graph;
98 	
99 	example_graph.edges = [
100 		"A": ["B"],
101 		"B": ["A", "C", "D"],
102 		"C": ["A"],
103 		"D": ["E", "A"],
104 		"E": ["B"]
105 	];
106 	
107 	breadth_first_search(example_graph, "A");
108 	
109 	// TODO: asserts
110 }
111 
112 unittest {
113 	SquareGrid!XY grid = SquareGrid!XY(30, 15);
114 	grid.walls = DIAGRAM1_WALLS;
115 	
116 	XY[] parents = breadth_first_search(grid, XY(8, 7));
117 	
118 	//TODO: asserts
119 }
120 
121 unittest {
122 	SquareGrid!XY grid = SquareGrid!XY(30, 15);
123 	grid.walls = DIAGRAM1_WALLS;
124 	
125 	XY[] parents = breadth_first_search(grid, XY(8, 7), XY(17, 2));
126 	
127 	//TODO: asserts
128 }
129 
130 /**
131  * Locates the next node in graph to get to a position
132  *
133  * Params:
134  *    graph		=	The graph of nodes
135  *    start		=	Starting position to go to
136  *    goal		=	The end position 
137  *    came_from	=	Output: An AA mapping a position to another to get to a point
138  *    distance	=	Output: Distance of a node to the end point
139  *
140  * See_Also:
141  *     http://www.redblobgames.com/pathfinding/tower-defense/
142  */
143 void breadth_first_search(T, U)(Graph graph, T start, T goal, out T[T] came_from, out U[T] distance) {
144 	Queue!T frontier;
145 	frontier.put(start);
146 	distance[start] = 0;
147 	
148 	while(!frontier.empty) {
149 		T current = frontier.get();
150 		if (current == goal)
151 			break;
152 		
153 		foreach(next; graph.neighbors(current)) {
154 			if (next !in came_from) {
155 				frontier.put(next);
156 				came_from[next] = current;
157 				distance[next] = 1 + distance[current];
158 			}
159 		}
160 	}
161 }